/**
 * 
 * @author Wouter
 * 
 */

package com.eDriveV2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class EcoCalculator {

	private HashMap<Integer, Integer> speedMap;

	public static double testValue;

	private final int Cev2 = 50;
	private final int Cev3 = 70;
	private final int Cev4 = 90;
	private final int Cev5 = 110;
	int count = 0;
	private String uberLabel = "";
	private ArrayList<Double> values = new ArrayList<Double>();

	public double calculateAcceleration(int speed1, int speed2) {
		double acceleration = 0;
		double differenceSpeed = speed2 - speed1;
		double differenceTime = 1;
		acceleration = differenceSpeed / differenceTime;
		return acceleration;

	}

	public EcoCalculator() {
		speedMap = new HashMap<Integer, Integer>();
	}

	/**
	 * @param deviation
	 *            , int
	 * @param mode
	 *            , int
	 */
	public String calculateEfficiency(double deviation, int mode) {
		String label = "";
		double value;
		int Ce = 0;
		if (mode < 50) {
			Ce = (int) calculateAvgSpeed();
		} // mode <= 50 then use avg speed
		else if (mode >= Cev2 && mode < Cev3) {
			Ce = Cev2;
		}// mode between 50 and 70
		else if (mode >= Cev3 && mode < Cev4) {
			Ce = Cev3;
		}// mode between 70 and 90
		else if (mode >= Cev4 && mode < Cev5) {
			Ce = Cev4;
		}// mode between 90 and 110
		else if (mode >= Cev5) {
			Ce = Cev5;
		}// mode above 110

		value = ((deviation * mode) / Ce);
		
		if (value == 0.0 || value == 0) {
			label = "?";
		}
		if (value <= 5 && value > 0.0) {
			label = "A";
		} else if (value > 5 && value <= 7) {
			label = "B";
		} else if (value > 7 && value <= 10) {
			label = "C";
		} else if (value > 10 && value <= 14) {
			label = "D";
		} else if (value > 14 && value <= 20) {
			label = "E";
		} else if (value > 20 && value <= 30) {
			label = "F";
		} else if (value > 30) {
			label = "G";
		} else {
			label = "Error";
		}
		testValue = value;
		values.add(value);// store each calculation of efficiency in an
							// arrayList. This is for share function
		return label;
	}

	public void putSpeed(int speed) {
		int dev = 0;
		ArrayList<Integer> al = new ArrayList<Integer>();
		if (count <= 10) {
			if (speedMap.containsKey(speed)) {
				speedMap.put(speed, speedMap.get(speed) + 1);
			} else {
				speedMap.put(speed, 1);
			}
			count++;
		} else {
			Collection speedC = speedMap.values();
			Collections speedMax = null;
			int valueOfMaxKey = speedMax.max(speedC);
			int modus = 0;
			for (int i : speedMap.keySet()) {
				if (speedMap.get(i).equals(valueOfMaxKey)) {
					modus = i;
				}
			}
			if (modus > 100) {
				dev = 7;
			}
			if (modus <= 100 && modus >= 70) {
				dev = 5;
			}
			if (modus < 70 && modus >= 50) {
				dev = 4;
			}
			if (modus < 50) {
				dev = 3;
			}
			for (int i : speedMap.keySet()) {
				if (speedMap.get(i) < (modus - dev)
						|| speedMap.get(i) > (modus + dev)) {
					al.add(i);
				}
			}
			int g = 0;
			for (int i : al) {
				g = i + g;
			}
			double deviation = 0;
			if (al.size() > 0) {
				deviation = Math.abs(g / al.size());
			}
			uberLabel = calculateEfficiency(deviation, modus);
			count = 0;
			speedMap.clear();
		}
	}
	/**
	 * Calculates the avg speed that are stored in the hashmap. Note only used
	 * if the mode of the speedMap is slower then 50
	 */
	public double calculateAvgSpeed() {
		/**
		 * double speed=1; int amountspeed=2; int amount=5; double total=0; for
		 * (int i=0;i<=speedMap.size();i++) {
		 * 
		 * // retrieve speed from hashMap // retrieve value for the matching
		 * speed, from hashMap // // total speed= total + (speed * amountspeed)
		 * // Amount = amount + aantal;
		 * 
		 * total = total+(speed*amountspeed); amount = amount+ amountspeed; }
		 * double avg = total/amount; return avg;
		 */
		double speed1;
		double amount = 0.0;
		double total = 0.0;
		double avg = 0.0;
		Set<Entry<Integer, Integer>> s = speedMap.entrySet();
		Iterator it = s.iterator();

		while (it.hasNext()) {
			// key=value separator this by Map.Entry to get key and value
			Map.Entry m = (Map.Entry) it.next();

			// getKey is used to get key of HashMap
			int key = (Integer) m.getKey();

			// getValue is used to get value of key in HashMap
			int value = (Integer) m.getValue();

			speed1 = key * value;
			amount = amount + value;
			total = total + speed1;
		}
		avg = (total / amount);
		return avg;
	}

	public String getUberLabel() {
		return uberLabel;
	}

	public String calculateAvgEfficiency() {
		String label = "";
		double total_value = 0;
		double value = 0;
		for (int i = 0; i < values.size(); i++) {
			total_value = values.get(i) + total_value;
		}
		value = total_value / values.size();
		if (value == 0.0 || value == 0) {
			label = "?";
		}
		if (value <= 5 && value > 0.0) {
			label = "A";
		} else if (value > 5 && value <= 7) {
			label = "B";
		} else if (value > 7 && value <= 10) {
			label = "C";
		} else if (value > 10 && value <= 14) {
			label = "D";
		} else if (value > 14 && value <= 20) {
			label = "E";
		} else if (value > 20 && value <= 30) {
			label = "F";
		} else if (value > 30) {
			label = "G";
		} else {
			label = "Error";
		}
		// values.removeAll(values);
		return label;
	}
}